param(
	[Parameter(Mandatory=$false)]                             
	[string]$inputFile="inputlist.txt",     # the input file to store vdi,domain and fid list
	[Parameter(Mandatory=$false)]                             
	[switch]$inputFileSaved,               # tell if inputfile has been saved, otherwise will popup text to let user enter VDI list.
	[Parameter(Mandatory=$false)]                             
	[switch]$functionInvoked              # tell if script needs to invoke functions
)
$st=get-date
$this_path = Split-Path -Parent ($MyInvocation.MyCommand.Definition) # get the directory of this running script
$parent_path=(get-item $this_path).Parent.FullName
If( !$functionInvoked ){
	. "$parent_path\functions.ps1" # import functions to powershell from functions.ps1
}
If( $inputFile -notlike "*\*"){
    $inputFile="$this_path\$inputFile"
}
$inputlist=Get-Inputlist $inputFile $inputFileSaved
#-------------------------------------------------Hardware Setting Checking------------------------------------------------------------------
$hardware_temppath="$this_path\temp" # used to store each result csv file from end vdi incase the script breaks in the middle of running unexpectedly so that we can check the file and know which ones we have already checked
del "$hardware_temppath\*.csv" -Force -ErrorAction Ignore
del "$this_path\*.csv" -Force -ErrorAction Ignore
New-FileOrFolder $hardware_temppath -d
$harware_action={
	param($line,$cnt,$ActionParams)
	try{$vdi,$domain,$fid,$env=$line.split(",").trim()}catch{}
	$hardware_temppath=$ActionParams
	$harware_info = [ordered]@{
		"Category/Setting"="$vdi/$fid/$domain";
		"System/CPU"=$null;
		"System/Memory"=$null;
		"System/HDD"=$null;
		"System/ScreenResolution"=$null}
	If(Test-Connection $vdi -quiet -count 1 -ErrorAction Ignore){
		write-host "Processing in $cnt-$vdi for hardware checking...`n"
		try{
			test-path "\\$vdi\c$\" -ErrorAction Stop 1>$null
		}catch{
			If($_.exception -like "*Access is denied*"){$registries.Set_Item("Category/Setting","$vdi/$fid/$domain Access denied")}
			$rst= New-Object PSObject -Property $registries
			Write-Host -ForegroundColor Red "$cnt-$vdi-Access denied"
			return $rst
		}
		$processor_info=Get-WmiObject -Class Win32_Processor -ComputerName $vdi 2>$null
		Switch ($processor_info.architecture) {
			0 { $arch = "x86" }
			1 { $arch = "MIPS" }
			2 { $arch = "Alpha" }
			3 { $arch = "PowerPC" }
			6 { $arch = "Itanium" }
			9 { $arch = "x64" }
		}
		#<-------------------1. set cpu info
		$harware_info.Set_Item("System/CPU",("{0} cores $arch {1}" -f $processor_info.NumberOfCores,$processor_info.Name))
		#<-------------------2. set memory info
		$harware_info.Set_Item("System/Memory",((Get-WmiObject CIM_PhysicalMemory).Capacity|Measure-Object -Sum|%{"{0:0.00}" -f ($_.sum / 1gb)}))
		#<-------------------3. set HDD info
		$harware_info.Set_Item("System/HDD",("{0:0.00}" -f ((Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='C:'").Size / 1gb)))
		#<-------------------4. set resolution info
		$rsl=Get-WmiObject -Class Win32_DesktopMonitor -cn $vdi | Select-Object ScreenWidth,ScreenHeight 
		$screen_width=$rsl.ScreenWidth ; $screen_height=$rsl.screenheight 
		If( $rsl.ScreenWidth -eq $null -or $rsl.ScreenHeight -eq $null){
		    $rsl=Get-WmiObject -class "Win32_DisplayConfiguration" -cn $vdi |select PelsWidth, PelsHeight
			$screen_width=$rsl.PelsWidth ; $screen_height=$rsl.PelsHeight
		}
		$harware_info.Set_Item("System/ScreenResolution","$screen_width x $screen_height")
	}else{
		$harware_info.Set_Item("Category/Setting","$vdi-invalid name or offline/$fid/$domain")
	}
	$rst= New-Object PSObject -Property $harware_info
	Write-Host -ForegroundColor Yellow "----$cnt-$vdi Done checking hardware info----`n"
	$rst|Export-Csv -Path "$hardware_temppath\$vdi-hardware.csv" -UseCulture -NoTypeInformation -Encoding UTF8 -Force -ErrorAction Ignore
	return $rst
}
$hardware_details = Start-BulkThreads $inputlist $harware_action $hardware_temppath -maxCnt 100|sort "Category/Setting"
Export-Result $hardware_details "hardware_details" "$this_path\hardware.csv" ([math]::Round(((get-date)-$st).totalseconds))
